package com.elinkway.infinitemovies.service;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;

import com.elinkway.infinitemovies.application.MoviesApplication;
import com.elinkway.infinitemovies.ui.activity.play.PlayerUtils;
import com.elinkway.infinitemovies.utils.LiteAppManager;
import com.elinkway.infinitemovies.utils.LogUtils;
import com.elinkway.infinitemovies.utils.MD5Utils;
import com.elinkway.infinitemovies.utils.NetWorkTypeUtils;
import com.elinkway.infinitemovies.utils.SharePreferenceManager;
import com.elinkway.infinitemovies.utils.StorageManager;
import com.elinkway.infinitemovies.utils.ToastUtil;
import com.elinkway.infinitemovies.utils.UpdateManager;
import com.elinkway.infinitemovies.utils.Utils;
import com.le123.ysdq.R;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class UpdateService extends Service {
    public static String TAG = "UpdateService";
    // wuxinrong added begin
    /**
     * 更新或下载时的Notification标题
     */
    private static String NOTIFICATION_TITLE_INFINITE_MOVIES_UPDATE;
    private static String NOTIFICATION_TITLE_LITE_APP_PLUGIN;
    /**
     * 更新类型-影视大全自身更新或LiteApp下载
     */
    public static final int UPDATE_TYPE_INFINITE_MOVIES = 0;
    public static final int UPDATE_TYPE_LITE_APP = 1;
    private int type;
    // wuxinrong added end

    //标题
    private int titleId = 0;

    //文件存储
    private File updateDir = null;
    private File updateFile = null;

    //通知栏
    private NotificationManager downloadNotificationManager = null;
    private NotificationCompat.Builder downloadNotificationBuilder = null;
    //通知栏跳转Intent
    private Intent updateIntent = null;
    private PendingIntent updatePendingIntent = null;
    private boolean cancelDownLoading = false;

    private boolean isInLoading = false;

    private final int COMPLETE = 0x00;

    private final int CANCEL = 0x01;

    private final int DOWN_ERROR = 0x02;

    private final int CANCEL_DOWNLOAD = 0x03;

    /**
     * 下载通知栏id
     */
    private final int id = 42;

    private boolean mDownErr;// 下载过程是否出错
    private static final String DOWN_FAIL = "下载失败,请返回重试";
    private static final String SDCARDNOEXIST = "当前没有SD卡";

    // 网络变化广播接收
    private NetworkCheckReceiver mCheckReceiver;

    private boolean isToInstall;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (null == intent) {
            stopSelf();
            return super.onStartCommand(intent, flags, startId);
        }
        NOTIFICATION_TITLE_INFINITE_MOVIES_UPDATE = getString(R.string.update_tips_title);
        NOTIFICATION_TITLE_LITE_APP_PLUGIN = getString(R.string.update_tips_lite_app_title);
        updateIntent = intent;
        registerCheckNetwork();
        String url = intent.getStringExtra("url");
        type = intent.getIntExtra("type", UPDATE_TYPE_INFINITE_MOVIES);
        isToInstall = intent.getBooleanExtra("isToInstall", false);
        if(UPDATE_TYPE_LITE_APP != type){
            //静默下载，通知栏不提示
            downloadNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            InputStream is = this.getResources().openRawResource(+R.drawable.ic_launcher);
            Bitmap mBitmap = BitmapFactory.decodeStream(is);
            // wuxinrong modified begin
            // 下载LiteApp时，我们会主动传入更新类型type，没有传入则去默认值 UPDATE_TYPE_INFINITE_MOVIES
            downloadNotificationBuilder = new NotificationCompat.Builder(this)
                    .setContentTitle(getNotificationTitleByType(type))
                    .setLargeIcon(mBitmap)
                    .setSmallIcon(android.R.drawable.stat_sys_download)
                    .setAutoCancel(false);
        }
        downLoadFile(url, "", type);
        // wuxinrong modified end
        return super.onStartCommand(intent, flags, startId);
    }

    // wuxinrong added begin
    private String getNotificationTitleByType(final int type) {
        String title = "";
        if (UPDATE_TYPE_INFINITE_MOVIES == type) {
            title = NOTIFICATION_TITLE_INFINITE_MOVIES_UPDATE;
        } else if (UPDATE_TYPE_LITE_APP == type) {
            title = NOTIFICATION_TITLE_LITE_APP_PLUGIN;
        } else {
            title = "未知更新";
        }
        return title;
    }
    // wuxinrong added end

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private Handler mMainHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case COMPLETE:
                    if (msg.arg1 == UPDATE_TYPE_LITE_APP) {
                        LogUtils.e(TAG, "安装安装安装！！！！！");
                        if (LiteAppManager.progressDialog != null && LiteAppManager.progressDialog.isShowing()) {
                            LiteAppManager.progressDialog.cancel();
                        }
                        LiteAppManager.getInstance().setDownloadState(LiteAppManager.DOWNLOAD_STATE_COMPLETE);
                        if(isToInstall){
                            String md5 = SharePreferenceManager.getVaule(UpdateService.this, SharePreferenceManager.LITE_APP_MD5, "");
                            String filePath = Environment.getExternalStorageDirectory().getPath() + "/" + LiteAppManager.LITE_APP_FILE_NAME;
                            if(TextUtils.isEmpty(md5) ? true : md5.equals(MD5Utils.md5File(filePath))){
                                installApk(updateFile);
                            }else{
                                updateFile.delete();
                            }

                        }
                    }else{
                        installApk(updateFile);
                    }
                    UpdateManager.setUpdating(false);
                    unregisterCheckNetwork();
                    stopService(updateIntent);
                    break;
                case CANCEL_DOWNLOAD:
                    if (msg.arg1 == UPDATE_TYPE_LITE_APP) {
                        if (LiteAppManager.progressDialog != null && LiteAppManager.progressDialog.isShowing()) {
                            LiteAppManager.progressDialog.cancel();
                        }
                        LiteAppManager.getInstance().setDownloadState(LiteAppManager.DOWNLOAD_STATE_FAILED);
                    }
                    UpdateManager.setUpdating(false);
                    unregisterCheckNetwork();
                    stopService(updateIntent);
                    break;
                case DOWN_ERROR:
                    // wuxinrong added begin
                    if (msg.arg1 == UPDATE_TYPE_LITE_APP) {
                        if (LiteAppManager.progressDialog != null && LiteAppManager.progressDialog.isShowing()) {
                            LiteAppManager.progressDialog.cancel();
                        }
                        LiteAppManager.getInstance().setDownloadState(LiteAppManager.DOWNLOAD_STATE_FAILED);
                    }
                    // wuxinrong added end
                    Object msgObi = msg.obj;
                    String errorMsg = null;
                    if (null != msgObi && msgObi instanceof String) {
                        errorMsg = (String) msgObi;
                    }
                    errorMsg = TextUtils.isEmpty(errorMsg) ? DOWN_FAIL : errorMsg;
                    UpdateManager.setUpdating(false);
                    unregisterCheckNetwork();
                    if(msg.arg1 == UPDATE_TYPE_LITE_APP){
                        //由于静默下载，并不提示
                    }else{
                        downloadNotificationBuilder.setProgress(0, 0, false)
                                .setOngoing(false)
                                .setSmallIcon(android.R.drawable.stat_sys_warning)
                                .setTicker(errorMsg)
                                .setContentText(errorMsg);
                        downloadNotificationManager.notify(id, downloadNotificationBuilder.build());
                        ToastUtil.showShortToast(MoviesApplication.getInstance(), R.string.downFailToast);
                    }
                    stopService(updateIntent);

                    break;
                default:
                    if (LiteAppManager.progressDialog != null && LiteAppManager.progressDialog.isShowing()) {
                        LiteAppManager.progressDialog.cancel();
                    }
                    unregisterCheckNetwork();
                    stopService(updateIntent);
                    break;
            }
            super.handleMessage(msg);
        }
    };

    /**
     * 开启下载线程
     *
     * @param url  下载网络路径
     * @param path 本地保存路径
     * @param type 下载类型，用于判断影视大全自身更新还是LiteApp下载
     */
    // wuxinrong modified begin
    protected void downLoadFile(final String url, final String path, final int type) {
        // wuxinrong modified end
        new Thread() {
            @Override
            public void run() {
                try {
                    if(UPDATE_TYPE_LITE_APP != type){
                        downloadNotificationBuilder.setProgress(0, 0, true)
                                .setOngoing(true)
                                .setSmallIcon(android.R.drawable.stat_sys_download)
                                .setTicker("开始下载")
                                .setContentText("正在连接");
                        downloadNotificationManager.notify(id, downloadNotificationBuilder.build());
                    }
                    LogUtils.e(TAG, "downLoadFile called");
                    mDownErr = false;
                    // wuxinrong modified begin
                    updateFile = getFileFromServer(url, path, type);
                    // wuxinrong modified end
                    if (null == updateFile) {
                        LogUtils.e(TAG, "down file is null and not need any opt");
                    } else if (!cancelDownLoading) {
                        LogUtils.e(TAG, "install or down fail");
                        if (mDownErr) {
                            LogUtils.e(TAG, "down fail and down part not all");
                            downErr(DOWN_FAIL, type);
                        } else {
                            LogUtils.e(TAG, "prepare install apk");
                            Message msg = mMainHandler.obtainMessage(COMPLETE);
                            msg.arg1 = type;
                            mMainHandler.removeMessages(COMPLETE);
                            mMainHandler.sendMessage(msg);
                        }
                    } else {
                        Message msg = mMainHandler.obtainMessage(CANCEL);
                        // wuxinrong added begin
                        msg.arg1 = type;
                        // wuxinrong added end
                        mMainHandler.removeMessages(CANCEL);
                        mMainHandler.sendMessage(msg);
                    }
                } catch (Exception e) {
                    LogUtils.e(TAG, "down file throws exception and msg is " + e.getMessage());
                    downErr(DOWN_FAIL, type);
                    e.printStackTrace();
                }
            }
        }.start();
    }

    /**
     * 开始下载
     *
     * @param urlpath   网络下载路径
     * @param localPath 本地保存路径
     * @param type      更新类型，用于判断是影视大全自身的更新还是LiteApp的下载
     * @return 返回File
     * @throws Exception
     */
    public synchronized File getFileFromServer(String urlpath, String localPath, final int type)
            throws Exception {
        LogUtils.e(TAG, "getFileFromServer called");
        //如果相等的话表示当前的sdcard挂载在手机上并且是可用的
        isInLoading = true;
        int downloadCount = 0;
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            LogUtils.e(TAG, "down url is " + urlpath);
            URL url = new URL(urlpath);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(6000);
            conn.setReadTimeout(6000);
            //获取到文件的大小
            int total_size = conn.getContentLength();
            LogUtils.e(TAG, "total_size is " + total_size);
            // 重试机制
            if (total_size <= 0) {
                LogUtils.e(TAG, "total_size is 0 and maybe url is err or net is weak");
                LogUtils.e(TAG, "direct downFail");
                downErr(DOWN_FAIL, type);
                return null;
            }
            if(UPDATE_TYPE_LITE_APP != type){
                downloadNotificationBuilder.setOngoing(true)
                        .setProgress(100, 0, false).setContentText("正在下载");
                downloadNotificationManager.notify(id,
                        downloadNotificationBuilder.build());
            }
            InputStream is = conn.getInputStream();
            // wuxinrong modified begin
            String name = Utils.YINGSHIDAQUAN;
            if (UPDATE_TYPE_LITE_APP == type) {
                name = LiteAppManager.LITE_APP_FILE_NAME;
            }
            File file = new File(Environment.getExternalStorageDirectory(), name);
            // wuxinrong modified end
            if (file.exists()) {
                LogUtils.e(TAG, "before down prepare delete apk ");
                boolean status = file.delete();
                LogUtils.e(TAG, "before down delete apk and status is " + status);
            }
            BufferedInputStream bis = new BufferedInputStream(is);
            FileOutputStream fos = new FileOutputStream(file);
            byte[] buffer = new byte[1024];
            int len;
            int current_size = 0;
//            LogUtils.e(TAG, "len is " + bis.read(buffer));
            while ((len = bis.read(buffer)) != -1 && !cancelDownLoading) {

                fos.write(buffer, 0, len);
                current_size += len;
                //获取当前下载量
                int current_progress = (current_size * 100) / total_size;
                if ((downloadCount == 0)
                        || current_progress - 10 > downloadCount) {
                    downloadCount += 10;
                    if(UPDATE_TYPE_LITE_APP != type) {
                        downloadNotificationBuilder
                                .setProgress(100, current_progress, false)
                                .setContentText(
                                        String.format(
                                                "正在下载 %1$s/%2$s",
                                                StorageManager
                                                        .bytes2humanity(current_size),
                                                StorageManager
                                                        .bytes2humanity(total_size)));
                        downloadNotificationManager.notify(id,
                                downloadNotificationBuilder.build());
                    }
                }
            }
            if (current_size != total_size) {
                mDownErr = true;
                LogUtils.e(TAG, "current_size is part or net is weak");
            } else
                LogUtils.e(TAG, "down sucess and current_size is " + current_size);
            fos.close();
            bis.close();
            is.close();
            isInLoading = false;
            return file;
        } else {
            LogUtils.e(TAG, "no sdcard and direct downFail");
            Message msg = mMainHandler.obtainMessage(DOWN_ERROR);
            msg.obj = SDCARDNOEXIST;
            mMainHandler.removeMessages(DOWN_ERROR);
            mMainHandler.sendMessage(msg);
            return null;
        }
    }

    /**
     * 取消下载
     */
    private void cancelDownLoad() {
        cancelDownLoading = true;
    }

    //安装apk
    protected void installApk(File file) {
        if (!cancelDownLoading && !mDownErr) {
            Intent intent = new Intent();
            //执行动作
            intent.setAction(Intent.ACTION_VIEW);
            //执行的数据类型
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            if(Build.VERSION.SDK_INT >= 24){
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                Uri contentUri = FileProvider.getUriForFile(this, this.getPackageName(), file);
                intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
            }else{
                intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
            }

            this.startActivity(intent);
            if(downloadNotificationManager != null){
                downloadNotificationManager.cancel(id);
            }
        } else
            LogUtils.e(TAG, "down err and not install apk");
    }

    /**
     * @param type LiteApp或者影视大全apk
     */
    private void downErr(String errInfo, int type) {
        LogUtils.e(TAG, "down err");
        Message msg = mMainHandler.obtainMessage(DOWN_ERROR);
        msg.obj = errInfo;
        msg.arg1 = type;
        mMainHandler.removeMessages(DOWN_ERROR);
        mMainHandler.sendMessage(msg);
    }

    /**
     * qinguoli 注册监听手机网络广播 接收
     */
    protected void registerCheckNetwork() {
        LogUtils.e(TAG, "!!!!!!!!!!!!!!!!!!!!!!!registerCheckNetwork called!!!!!!!!!!!!!!!!!!!!!!!");
        mCheckReceiver = new NetworkCheckReceiver();
        IntentFilter intentfilter = new IntentFilter();
        intentfilter.addAction(PlayerUtils.CONNECTIVTY_CHANGE);
        this.registerReceiver(mCheckReceiver, intentfilter);
    }

    /**
     * qinguoli 取消对网络变化的监听*
     */
    protected void unregisterCheckNetwork() {
        if (mCheckReceiver != null) {
            LogUtils.e(TAG, "!!!!!!!!!!!!!!!!!!!!!!!unregisterCheckNetwork called!!!!!!!!!!!!!!!!!!!!!!!");
            try {
                this.unregisterReceiver(mCheckReceiver);
            } catch (IllegalArgumentException e) {
                if (e.getMessage().contains("Receiver not registered")) {
                    LogUtils.e(TAG, "!!!!!!!!!!!!!!!!!ignore incorrect unregisterCheckNetwork!!!!!!!!!!!!!!!!!");
                    LogUtils.e(TAG, "msg is " + e.getMessage());
                    // Ignore this exception. This is exactly what is desired
                } else {
                    // unexpected, re-throw
                    throw e;
                }
            }
        }
    }

    /**
     * qinguoli 网络广播监听*
     */
    class NetworkCheckReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
                if (intent.getAction().equals(PlayerUtils.CONNECTIVTY_CHANGE)) {
                    LogUtils.e(TAG, "!!!!!!!!!!!!!!!!!!!!!!!net change!!!!!!!!!!!!!!!!!!!!!!!");
                    int nowNetType = NetWorkTypeUtils.getNetType();
                    if (nowNetType == 0) {
                        LogUtils.e(TAG, "net is unavailable");
                        downErr(DOWN_FAIL, type);
                    } else
                        LogUtils.e(TAG, "cur netType is " + nowNetType);
                }
            }
        }
    }
}
